package com.witsoft.device.controller;

import com.alibaba.fastjson.JSONObject;
import com.witsoft.device.entity.DeviceEntity;
import com.witsoft.device.entity.DeviceMetricsLogEntity;
import com.witsoft.device.enums.MachineStatusEnum;
import com.witsoft.device.enums.Status;
import com.witsoft.device.model.*;
import com.witsoft.device.service.DeviceMetricsLogService;
import com.witsoft.device.service.DeviceReporterService;
import com.witsoft.device.service.DeviceService;
import com.witsoft.device.service.DeviceStatusTimeLineService;
import com.witsoft.device.utils.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;

@Slf4j
@RestController
@Api(tags = "设备信息Controller", description = "设备信息")
@RequestMapping("/iot/device")
public class DeviceController{

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private DeviceStatusTimeLineService deviceStatusTimeLineService;

    @Autowired
    private DeviceMetricsLogService deviceMetricsLogService;

    @Value("${spring.rabbitmq.runMq}")
    private Boolean runMq;

    //性能开动率 标准节拍(配置参数值，可由mes传过来)/（运行时间/生产产量）*100%
    @Value("${gongli.device.setPerformance}")
    private Integer setPerformance;

    @Resource
    private DeviceReporterService reporterService;



    @GetMapping
    @ApiOperation(value = "设备列表")
    public Result list() throws IOException{

        try{
            List<DeviceEntity> list = deviceService.getAllList();

            return Result.success(list);
        }catch (Exception e){
            log.error("设备列表获取异常：{}", e.getMessage());
            return Result.error(Status.ERROR);
        }
    }



    @GetMapping(value = "/getAverageDeviceTarget")
    @ApiOperation(value = "所有设备平均指标")
    public Result getAverageDeviceTarget(){

        try{
            DeviceQuotaListInfo averageDeviceTarget = deviceService.getAverageDeviceTarget();
            return Result.success(averageDeviceTarget);

        }catch (Exception e){
            log.error("获取设备平均指标异常：{}", e.getMessage());
            return Result.error(Status.ERROR);
        }
    }




    @GetMapping(value = "/getDeviceMetricsLog")
    @ApiOperation(value = "设备指标")
    public Result getDeviceMetricsLog(String deviceId){
        JSONObject result = new JSONObject();
        try{

            DecimalFormat df = new DecimalFormat("#.00");
            DeviceEntity deviceEntity = deviceService.getInfo(deviceId);

            //合格率 合格数量/总数量
            double quantityRate = (deviceEntity.getTotalCount()==null || deviceEntity.getTotalCount()==0)?0:(1.0*deviceEntity.getGoodCount())/deviceEntity.getTotalCount();

            //取当前设备当天的所有运行时长(单位：秒)
            int sumRunning = deviceStatusTimeLineService.getSumRunningTimeDay(deviceEntity.getId());

            double performanceRate = 0;
            if(null != deviceEntity.getTotalCount() && deviceEntity.getTotalCount() > 0 && sumRunning > 0){
                performanceRate = (1.0*setPerformance) / (1.0*sumRunning / deviceEntity.getTotalCount());
            }

            //时间开动率
            //取当前设备当天的所有记录时长(单位：秒)
            int sumTime = deviceStatusTimeLineService.getSumTime(deviceEntity.getId());
            double availability = sumTime <= 0 ? 0 : (1.0 * sumRunning) / sumTime;
            //oee
            double oeeRate = quantityRate * performanceRate * availability;

            result.put("quantity", quantityRate <= 0 ? "0" : df.format(quantityRate*100));
            result.put("performance", performanceRate <= 0 ? "0" : df.format(performanceRate*100));
            result.put("availability", availability <= 0 ? "0" : df.format(availability*100));
            result.put("oee", oeeRate <= 0 ? "0" : df.format(oeeRate*100));
        }catch (Exception e){
            log.error("设备指标查询异常：{}", e.getMessage());
            return Result.error(Status.DEVICE_INDEX_FAILED);
        }
        return Result.success(result);
    }



    @PostMapping(value = "/reportStatus")
    @ApiOperation(value = "上报设备数据")
    public Result reportStatus(@RequestBody @Valid String obj) {

        try {
            if(runMq){
                //走mq
                deviceStatusTimeLineService.reportStatusSplitFlow(obj);
            }else{
                deviceStatusTimeLineService.reportStatusNoSplitFlow(obj);
            }
            return Result.success(Status.SUCCESS);

        } catch (Exception e) {
            log.error("设备状态上报异常：{}", e.getMessage());
            return Result.error(Status.REPORT_FAILED);
        }
    }


    @PostMapping(value = "/calacMetricsOfHour")
    @ApiOperation(value = "设备指标计算测试接口")
    public void calacMetricsOfHour() {
        List<DeviceEntity> deviceList = deviceService.getAllList();
        if(null != deviceList && deviceList.size() > 0){

            Date dtNow = new Date();
            Calendar cal = Calendar.getInstance();
            cal.setTime(dtNow);
            cal.set(Calendar.MILLISECOND,0);
            cal.set(Calendar.MINUTE,0);
            cal.set(Calendar.SECOND,0);
            for(DeviceEntity deviceEntity : deviceList){
                DecimalFormat df = new DecimalFormat("#.00");

                //合格率 合格数量/总数量
                double quantityRate = (deviceEntity.getTotalCount()==null || deviceEntity.getTotalCount()==0)?0:(1.0*deviceEntity.getGoodCount())/deviceEntity.getTotalCount();

                //性能开动率 标准节拍(配置参数值，可由mes传过来)/（运行时间/生产产量）*100%
                double setPerformance = deviceEntity.getDeviceMeter();//做成配置文件参数  单位：S

                //取当前设备当天的所有运行时长(单位：秒)
                int sumRunning = deviceStatusTimeLineService.getSumRunningTimeDay(deviceEntity.getId());

                double performanceRate = 0;
                if(deviceEntity.getTotalCount()==null || deviceEntity.getTotalCount()==0 || sumRunning==0){
                    performanceRate = 0;
                }else{
                    performanceRate = (1.0*setPerformance)/(1.0*sumRunning/deviceEntity.getTotalCount());
                }

                //时间开动率
                //取当前设备当天的所有记录时长(单位：秒)
                int sumTime = deviceStatusTimeLineService.getSumTime(deviceEntity.getId());
                double availability = sumTime <= 0 ? 0 : (1.0*sumRunning)/sumTime;
                //oee
                double oeeRate = quantityRate*performanceRate*availability;

                DeviceMetricsLogEntity log = new DeviceMetricsLogEntity();
                log.setId(UUID.randomUUID().toString());
                log.setDeviceId(deviceEntity.getId());

                log.setQuality(quantityRate <= 0 ? "0" : df.format(quantityRate*100));
                log.setPerformance(performanceRate <= 0 ? "0" : df.format(performanceRate*100));
                log.setAvailability(availability <= 0 ? "0" : df.format(availability*100));
                log.setOee(oeeRate <= 0 ? "0" : df.format(oeeRate*100));

                log.setGoodCount(deviceEntity.getGoodCount());
                log.setBadCount(deviceEntity.getBadCount());
                log.setTotalCont(deviceEntity.getTotalCount());
                log.setCreateTime(cal.getTime());
                log.setType("hour");
                deviceMetricsLogService.save(log);
            }
        }
    }



    @ApiOperation(value = "设备状态分布饼图")
    @GetMapping("/deviceTotalInfo")
    public Result deviceStatusPieChart(){

        Integer sum = 0;
        Integer openSum = 0;
        DecimalFormat df = new DecimalFormat("#");

        List<EchartVO> datas = new ArrayList<>();
        DeviceTotalInfo deviceTotalInfo = new DeviceTotalInfo(sum, datas);

        List<DeviceTotalInfo> deviceTotalInfos = deviceService.getDeviceTotalInfo();
        for (DeviceTotalInfo totalInfo: deviceTotalInfos) {
            sum = sum + totalInfo.getCount();
            MachineStatusEnum instance = MachineStatusEnum.getInstance(totalInfo.getStatus());

            EchartVO echartVO = new EchartVO(instance.getMsg(), totalInfo.getCount());
            echartVO.setStatus(totalInfo.getStatus().toString());

            if(instance == MachineStatusEnum.STOPPING){
                echartVO.setName(instance.getAlias());
            }

            datas.add(echartVO);
            //fixed（2021.11.08）: 开机数量 = 运行数量 + 待机数量
            if(instance == MachineStatusEnum.RUNNING || instance == MachineStatusEnum.WAITING){
                openSum += totalInfo.getCount();
            }

            if(instance == MachineStatusEnum.ERROR){
                deviceTotalInfo.setErrorNum(totalInfo.getCount());
            }

        }

        deviceTotalInfo.setTotal(sum);
        deviceTotalInfo.setRunningNum(openSum);

        //v3:
        //处理当日设备时间稼动率 = sum(单个设备当日运行时间 / 单个设备开机时间）/设备数
        Double timeGrainRateByDay = reporterService.getAllDeviceAverageTimeGrainRateByDay();
        deviceTotalInfo.setGrainMoveRate(df.format(100 * timeGrainRateByDay));


        //v2：
        //处理当日所有设备稼动率 = 所有设备运行时间/所有设备开机时间 * 100%
        /*deviceTotalInfo.setGrainMoveRate("0");
        Long allOpeningTimeDay = deviceStatusTimeLineService.getSumAllOpeningTimeDay();
        Long sumAllRunningTimeDay = deviceStatusTimeLineService.getSumAllRunningTimeDay();

        //fixed（2021.11.11）：获取当日连续运行和开机设备（没有标记total_spent值的记录）的时长
        Long totalSpentIsNull = deviceStatusTimeLineService.getSumAllOpeningTimeDayOfTotalSpentIsNull();
        Long runningTimeSpentIsNull = deviceStatusTimeLineService.getSumAllRunningTimeDayOfTotalSpentIsNull();
        log.info("统计的连续运行的设备实时开机时间：{}，连续运行的设备实时运行时间：{}", totalSpentIsNull, runningTimeSpentIsNull);

        //累加
        allOpeningTimeDay += totalSpentIsNull;
        sumAllRunningTimeDay += runningTimeSpentIsNull;

        if(allOpeningTimeDay > 0){
            Double rate = 100 * 1.0 * sumAllRunningTimeDay / allOpeningTimeDay;
            deviceTotalInfo.setGrainMoveRate(df.format(rate));
        }*/


        //v1:
        /*Result averageDeviceTarget = getAverageDeviceTarget();
        if(averageDeviceTarget.isSuccess()){
            DeviceQuotaListInfo data = (DeviceQuotaListInfo)averageDeviceTarget.getData();
            Integer performance = Integer.parseInt(data.getAllPerformance());
            Integer availability = Integer.parseInt(data.getAllAvailability());
            Integer quantity = Integer.parseInt(data.getAllQuantity());

            deviceTotalInfo.setGrainMoveRate(String.valueOf(performance * availability * quantity / 10000));
        }*/

        //处理饼图百分比
        datas.forEach(echartVO -> {
            Integer value = echartVO.getValue();
            Double rate = value.doubleValue() / deviceTotalInfo.getTotal() * 100;
            echartVO.setValue(Integer.parseInt(df.format(rate)));
        });
        return Result.success(deviceTotalInfo);
    }
}
